<template>
  <div class="app-container">
    <el-row :gutter="20" class="m-b-5">
      <el-col :span="24" class="m-b-20">
        <el-card shadow="hover">
          <div slot="header" class="clearfix">
            <label>基本信息</label>
          </div>
          <el-row style="line-height: 38px;">
            <el-col :span="2">Redis版本</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.redis_version }}</span></el-col>
            <el-col :span="2">运行模式</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</span></el-col>
            <el-col :span="2">端口</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.tcp_port }}</span></el-col>
            <el-col :span="2">客户端数</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.connected_clients }}</span></el-col>
          </el-row>
          <el-row style="line-height: 38px;">
            <el-col :span="2">运行时间(天)</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.uptime_in_days }}</span></el-col>
            <el-col :span="2">使用内存</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.used_memory_human }}</span></el-col>
            <el-col :span="2">使用CPU</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</span></el-col>
            <el-col :span="2">内存配置</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.maxmemory_human }}</span></el-col>
          </el-row>
          <el-row style="line-height: 38px;">
            <el-col :span="2">AOF是否开启</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.aof_enabled === "0" ? "否" : "是" }}</span></el-col>
            <el-col :span="2">RDB是否成功</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</span></el-col>
            <el-col :span="2">Key数量</el-col>
            <el-col :span="4"><span v-if="cache.dbSize">{{ cache.dbSize }}</span></el-col>
            <el-col :span="2">网络入口/出口</el-col>
            <el-col :span="4"><span v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</span></el-col>
          </el-row>
        </el-card>
      </el-col>

      <el-col :span="12" class="m-b-20">
        <el-card shadow="hover" class="w-100">
          <div slot="header" class="clearfix">
            <label>命令统计</label>
          </div>
          <div class="el-table el-table--enable-row-hover el-table--medium">
            <div ref="commandstats" style="height: 300px" />
          </div>
        </el-card>
      </el-col>

      <el-col :span="12" class="m-b-20">
        <el-card shadow="hover" class="w-100">
          <div slot="header" class="clearfix">
            <label>内存信息</label>
          </div>
          <div class="el-table el-table--enable-row-hover el-table--medium">
            <div ref="usedmemory" style="height: 300px" />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="10" class="m-b-5">
      <el-col :span="14" class="m-b-5">
        <el-card>
          <div slot="header">
            <label>键名列表</label>
            <el-button style="float: right; padding: 3px 0" type="text" icon="el-icon-refresh-right" @click="refreshKeys" />
            <el-button style="float: right; padding: 3px 0; margin-right: 10px" type="text" icon="el-icon-search" @click="handleSearchKeys()" />
          </div>
          <el-table ref="cache_key_table"
                    v-loading="tableLoading"
                    :data="cacheKeyData"
                    height="400px"
                    @row-click="handleKeyValue">
            <el-table-column align="center" label="缓存键名" show-overflow-tooltip>
              <template slot-scope="scope">{{ scope.row }}</template>
            </el-table-column>
            <el-table-column align="center" label="操作" width="60">
              <template slot-scope="scope">
                <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteKey(scope.row)" />
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>

      <el-col :span="10">
        <el-card :bordered="false" style="height: 490px">
          <div slot="header">
            <label>缓存内容</label>
            <el-button style="float: right; padding: 3px 0" type="text" icon="el-icon-refresh-right" @click="handleDeleteKeys()">清理全部</el-button>
          </div>
          <el-form :model="cacheForm">
            <el-row :gutter="32">
              <el-col :offset="1" :span="22">
                <el-form-item label="缓存键名:" prop="key">
                  <el-input v-model="cacheForm.key" readonly />
                </el-form-item>
              </el-col>
              <el-col :offset="1" :span="22">
                <el-form-item label="缓存内容:" prop="value">
                  <el-input v-model="cacheForm.value" type="textarea" :rows="13" readonly />
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { redisInfo, redisKeyDelete, redisKeyList, redisKeyValue } from '@/api/system/log'
import echarts from 'echarts'

export default {
  name: 'RedisServer',
  data () {
    return {
      // 统计命令信息
      commandstats: undefined,
      // 使用内存
      usedmemory: undefined,
      // cache 信息
      cache: {},
      // key 列表
      tableLoading: true,
      cacheKeyData: [],
      cacheForm: {}
    }
  },
  created () {
    this.getCacheInfo()
  },
  methods: {
    /** 查缓存询信息 */
    getCacheInfo () {
      this.$modal.loading('正在加载缓存监控数据, 请稍后...')
      // 查询 Redis 监控信息
      redisInfo().then((response) => {
        this.cache = response.param
        this.$modal.closeLoading()

        this.commandstats = echarts.init(this.$refs.commandstats, 'macarons')
        const commandStats = []
        response.param.commandStats.forEach(row => {
          commandStats.push({
            name: row.command,
            value: row.calls
          })
        })
        this.commandstats.setOption({
          tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)'
          },
          series: [
            {
              name: '命令',
              type: 'pie',
              roseType: 'radius',
              radius: [15, 95],
              center: ['50%', '38%'],
              data: commandStats,
              animationEasing: 'cubicInOut',
              animationDuration: 1000,
            },
          ],
        });
        this.usedmemory = echarts.init(this.$refs.usedmemory, 'macarons')
        this.usedmemory.setOption({
          tooltip: {
            formatter: '{b} <br/>{a} : ' + this.cache.info.used_memory_human
          },
          series: [
            {
              name: '峰值',
              type: 'gauge',
              min: 0,
              max: 1000,
              detail: {
                formatter: this.cache.info.used_memory_human
              },
              data: [
                {
                  value: parseFloat(this.cache.info.used_memory_human),
                  name: '内存消耗',
                },
              ],
            },
          ],
        })
      }).catch(() => {
        this.$modal.closeLoading()
      })

      // 查询 Redis Key 列表
      redisKeyList('').then(response => {
        this.cacheKeyData = response.param
        this.tableLoading = false
      }).catch(() => { this.tableLoading = false })
    },
    // 刷新键名列表
    refreshKeys() {
      this.tableLoading = true
      redisKeyList('').then(response => {
        this.cacheKeyData = response.param
        this.tableLoading = false
        this.$refs.cache_key_table.bodyWrapper.scrollTop = 0
      }).catch(() => { this.tableLoading = false })
    },
    // 获取缓存值
    handleKeyValue(key) {
      redisKeyValue(key + '').then(response => {
        this.cacheForm = {
          key: key,
          value: response.param
        }
      })
    },
    handleSearchKeys() {
      this.$prompt('请输入键名模板', '搜索', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(({ value }) => {
        if (value) {
          this.tableLoading = true
          redisKeyList(value).then(response => {
            this.cacheKeyData = response.param
            this.tableLoading = false
            this.$refs.cache_key_table.bodyWrapper.scrollTop = 0
          }).catch(() => { this.tableLoading = false })
        }
      }).catch(() => {})
    },
    // 删除缓存
    handleDeleteKey(key) {
      redisKeyDelete({ key: key }).then(() => {
        this.$modal.msgSuccess('清理缓存[' + key + ']成功')
        this.refreshKeys();
      })
    },
    handleDeleteKeys() {
      this.$prompt('请输入键名模板', '清理缓存', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(({ value }) => {
        if (value) {
          redisKeyDelete({ template: value }).then(() => {
            this.$modal.msgSuccess('清理缓存模板[' + value + ']成功')
            this.refreshKeys();
          })
        }
      }).catch(() => {})
    }
  }
}
</script>
